package com.delivery.deliverysystem.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.delivery.deliverysystem.common.ServerResponse;
import com.delivery.deliverysystem.dao.DeliveryMapper;
import com.delivery.deliverysystem.exception.RException;
import com.delivery.deliverysystem.pojo.DAO.*;
import com.delivery.deliverysystem.pojo.DO.Delivery;
import com.delivery.deliverysystem.pojo.DO.DeliveryColor;
import com.delivery.deliverysystem.pojo.VO.CadExcelListVO;
import com.delivery.deliverysystem.pojo.VO.DefaultNameVO;
import com.delivery.deliverysystem.pojo.VO.DeliveryVO;
import com.delivery.deliverysystem.service.DeliveryColorService;
import com.delivery.deliverysystem.service.DeliveryService;
import com.delivery.deliverysystem.service.NumberRuleService;
import com.delivery.deliverysystem.service.impl.ExcelServiceImpl;
import com.delivery.deliverysystem.service.impl.PdfServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@RestController
@RequestMapping("/delivery")
@Api(tags = "送货接口")
@Slf4j
public class DeliveryController {

    @Autowired
    private DeliveryService deliveryService;
    @Autowired
    private ExcelServiceImpl excelServiceImpl;
    @Value("${file.excel-path}")
    private String filePath;
    @Autowired
    private PdfServiceImpl pdfService;
    @Autowired
    private DeliveryColorService deliveryColorService;
    @Autowired
    private NumberRuleService numberRuleService;
    @Autowired
    private DeliveryMapper deliveryMapper;


    @GetMapping("/getCurrentUser")
    @ApiOperation(value = "获取制单人",response = ServerResponse.class,httpMethod = "GET")
    public ServerResponse getCurrentUser(){
        String currentUser = deliveryService.getCurrentUser();
        if(currentUser==null) return ServerResponse.createByError("获取制单人失败");
        return ServerResponse.createBySuccess(currentUser);
    }


    @PostMapping("/addDelivery")
    @ApiOperation(value = "添加送货单",response = ServerResponse.class,httpMethod = "POST")
    public ServerResponse addDelivery(@RequestBody DeliveryDTO deliveryDTO) throws Exception {
        try {
            String result = deliveryService.addDelivery(deliveryDTO);
            return ServerResponse.createBySuccess("添加成功", result);
        } catch (RException re) {
            log.error("添加送货单时出错: {}", deliveryDTO, re);
            return ServerResponse.createByError(re.getMessage());
        } catch (Exception e) {
            log.error("添加送货单时出错: {}", deliveryDTO, e);
            return ServerResponse.createByError("添加失败");
        }
    }

    @PostMapping("/updateDelivery")
    @ApiOperation(value = "修改送货单",response = ServerResponse.class,httpMethod = "POST")
    public ServerResponse updateDelivery(@RequestBody DeliveryDTO deliveryDTO){
        boolean b = false;
        try {
            b = deliveryService.updateDelivery(deliveryDTO);
            if(b) return ServerResponse.createBySuccess("修改成功");
            else return ServerResponse.createByError("修改失败");
        } catch (RException re){
            return ServerResponse.createByError(re.getMessage());
        } catch (Exception e) {
            log.error("修改送货单时出错: {}", deliveryDTO, e);
            return ServerResponse.createByError("修改失败");
        }
    }

    @DeleteMapping("/deleteDelivery")
    @ApiOperation(value = "删除送货单",response = ServerResponse.class,httpMethod = "DELETE")
    public ServerResponse deleteDelivery(@RequestParam String id){
        boolean b = deliveryService.deleteDelivery(id);
        if(b) return ServerResponse.createBySuccess("删除成功");
        else return ServerResponse.createByError("删除失败,没有该送货单");
    }

    @GetMapping("/getDeliveryById")
    @ApiOperation(value = "根据id获取送货单",response = ServerResponse.class,httpMethod = "GET")
    public ServerResponse getDeliveryById(@RequestParam String id){
        DeliveryVO deliveryById = deliveryService.getDeliveryById(id);
        if(deliveryById==null) return ServerResponse.createByError("没有该送货单");
        return ServerResponse.createBySuccess(deliveryById);
    }

    @GetMapping("/getDeliveryList")
    @ApiOperation(value = "获取送货单列表",response = ServerResponse.class,httpMethod = "GET")
    public ServerResponse getDeliveryList(@RequestParam(defaultValue = "1", name = "pageNum") int pageNum,
                                          @RequestParam(defaultValue = "10", name = "pageSize") int pageSize){
        IPage<Delivery> deliveryPage = null;
        try {
            deliveryPage = deliveryService.getDeliveryList(pageNum, pageSize);
            Map<String, Object> result = new HashMap<>();
            result.put("records", deliveryPage.getRecords());
            result.put("total", deliveryPage.getTotal());
            result.put("current", deliveryPage.getCurrent());
            result.put("size", deliveryPage.getSize());
            return ServerResponse.createBySuccess(result);
        } catch (RException e) {
            e.getMessage();
            return ServerResponse.createByError(e.getMessage());
        }
    }

    @GetMapping("/getDisplayField")
    @ApiOperation(value = "获取当前用户表格工件的显示字段",response = ServerResponse.class,httpMethod = "GET")
    public ServerResponse getDisplayField(){
        List<DefaultNameVO> displayField = null;
        try {
            displayField = deliveryService.getDisplayField();
            if(displayField==null || displayField.isEmpty()) return ServerResponse.createByError("获取字段失败");
            return ServerResponse.createBySuccess(displayField);
        } catch (RException re){
            return ServerResponse.createByError(re.getMessage());
        } catch (Exception e) {
            log.error("获取当前用户表格工件的显示字段时出错: {}", e);
            return ServerResponse.createByError("获取字段失败");
        }

    }

    @PostMapping("/updateDisplayField")
    @ApiOperation(value = "编辑送货单字符显示",response = ServerResponse.class,httpMethod = "POST")
    public ServerResponse updateDisplayField(@RequestBody FieldDisplayDTO fieldDisplayDTO){
        boolean b = false;
        try {
            b = deliveryService.updateDisplayField(fieldDisplayDTO);
            if(b) return ServerResponse.createBySuccess("修改成功");
            return ServerResponse.createByError("修改失败");
        } catch (RException re){
            return ServerResponse.createByError(re.getMessage());
        } catch (Exception e) {
            log.error("编辑送货单字符显示时出错: {}", fieldDisplayDTO, e);
            return ServerResponse.createByError("修改失败");
        }
    }
    @GetMapping("/getCADExcelList")
    @ApiOperation(value = "从某个盘下获取cad识别后的excel文件列表",response = ServerResponse.class,httpMethod = "GET")
    public Map<String, Object> getCADExcelList()throws IOException {
        Path path = Paths.get(filePath);
        try (Stream<Path> paths = Files.walk(path)) {
            List<Path> excelFiles = paths
                    .filter(Files::isRegularFile)
                    .filter(p -> p.toString().endsWith(".xlsx") || p.toString().endsWith(".xls"))
                    .collect(Collectors.toList());

            List<String> nameList = new ArrayList<>(); // 存储文件名
            List<CadExcelListVO> allData = new ArrayList<>();
            for (Path file : excelFiles) {
                String fileName = file.getFileName().toString();
                nameList.add(fileName);
                List<CadExcelListVO> dataList = excelServiceImpl.readExcelFile(file.toString());
                allData.addAll(dataList);
            }
            Map<String, Object> result = new HashMap<>();
            result.put("nameList", nameList);
            result.put("data", allData);
            return result;
        }
    }
    @Value("${server.port}")
    private Integer port;

    @PostMapping("/pdfExport")
    @ApiOperation(value = "打印pdf文件", response = ServerResponse.class, httpMethod = "POST")
    public ResponseEntity<Map<String, String>> pdfExport(
            @RequestBody PdfDAO pdfDAO,
            @RequestParam Integer type) throws Exception {
        // 1. 将对象转为JSON
        String jsonStr = new ObjectMapper().writeValueAsString(pdfDAO);

        // 2. 使用 URL 安全的 Base64 编码（避免 + / = 问题）
        String base64Data = Base64.getUrlEncoder().encodeToString(jsonStr.getBytes(StandardCharsets.UTF_8));

        // 3. 对 Base64 字符串进行 URL 编码（防止特殊字符截断）
        String encodedData = URLEncoder.encode(base64Data, "UTF-8");

        // 4. 根据 type 选择模板
        String templateName;
        String filename = URLEncoder.encode(
                pdfDAO.getFullName() + pdfDAO.getDeliveryDate() + "送货单",
                "UTF-8"
        );


        Map<String, String> urls = new HashMap<>();
        switch (type) {
            case 1:
                templateName = "A4送货单报表.ureport.xml";
                break;
            case 2:
                templateName = "二等分A4送货单报表.ureport.xml";
                break;
            case 3:
                templateName = "三等分A4送货单报表.ureport.xml";
                break;
            default:
                throw new IllegalArgumentException("暂时没有该类型: " + type);
        }

        // 构建携带数据的URL
        String baseUrl = "http://localhost:" + port + "/ureport/preview?_u=file:" + templateName;
        urls.put("previewUrl", baseUrl + "&_n=" + filename + "&data=" + encodedData);
        urls.put("designUrl", "http://localhost:" + port + "/ureport/designer?_u=file:" + templateName);
        urls.put("downloadUrl","http://localhost:" + port + "/ureport/pdf?_u=file:" + templateName + "&_n=" + filename + "&data=" + encodedData);

        //修改打印状态
        String deliveryId = pdfDAO.getDeliveryNumber();
        if (StringUtils.hasText(deliveryId)) {
            deliveryMapper.updateStatusToPrinted(deliveryId);
        }
        return ResponseEntity.ok(urls);
    }
    @PostMapping("/reconciliationExport")
    @ApiOperation(value = "对账单导出", response = ServerResponse.class, httpMethod = "POST")
    public ServerResponse reconciliationExport(@RequestBody ReconciliationDAO reconciliationDAO)
            throws UnsupportedEncodingException, JsonProcessingException {
        // 1. 将对象转为JSON
        String jsonStr = new ObjectMapper().writeValueAsString(reconciliationDAO);

        // 2. 使用 URL 安全的 Base64 编码（避免 + / = 问题）
        String base64Data = Base64.getUrlEncoder().encodeToString(jsonStr.getBytes(StandardCharsets.UTF_8));

        // 3. 对 Base64 字符串进行 URL 编码（防止特殊字符截断）
        String encodedData = URLEncoder.encode(base64Data, "UTF-8");

        // 生成文件名（URL编码避免乱码）
        String fileName = URLEncoder.encode(
                reconciliationDAO.getFullName() + reconciliationDAO.getBeginTime() + "对账单",
                "UTF-8"
        );

        // 构建携带数据的导出URL
        String exportUrl = "http://localhost:" + port + "/ureport/excel" +
                "?_u=file:对账单模板.ureport.xml" +
                "&_n=" + fileName +
                "&data=" + encodedData; // 关键：直接携带数据参数

        return ServerResponse.createBySuccess(exportUrl);
    }

    @PostMapping("/labelExport")
    @ApiOperation(value = "各公司标签表导出", response = ServerResponse.class, httpMethod = "POST")
    public ServerResponse labelExport(@RequestBody LabelDAO labelDAO)
            throws JsonProcessingException, UnsupportedEncodingException {

        // 1. 将对象转为JSON
        String jsonStr = new ObjectMapper().writeValueAsString(labelDAO);

        // 2. 使用 URL 安全的 Base64 编码（避免 + / = 问题）
        String base64Data = Base64.getUrlEncoder().encodeToString(jsonStr.getBytes(StandardCharsets.UTF_8));

        // 3. 对 Base64 字符串进行 URL 编码（防止特殊字符截断）
        String encodedData = URLEncoder.encode(base64Data, "UTF-8");

        // 生成文件名（URL编码）
        String fileName = URLEncoder.encode(
                labelDAO.getClientName() + "标签表.xlsx",
                "UTF-8"
        );

        //构建导出URL（携带数据参数）
        String exportUrl = "http://localhost:" + port + "/ureport/excel" +
                "?_u=file:公司标签表.ureport.xml" +
                "&_n=" + fileName +
                "&data=" + encodedData; // 使用明确参数名

        return ServerResponse.createBySuccess(exportUrl);
    }

    @PostMapping("/detectReportExport")
    @ApiOperation(value = "检测报告导出", response = ServerResponse.class, httpMethod = "POST")
    public ServerResponse detectReportExport(@RequestBody DetectReportDAO detectReportDAO)
            throws JsonProcessingException, UnsupportedEncodingException {
        // 1. 将对象转为JSON
        String jsonStr = new ObjectMapper().writeValueAsString(detectReportDAO);

        // 2. 使用 URL 安全的 Base64 编码（避免 + / = 问题）
        String base64Data = Base64.getUrlEncoder().encodeToString(jsonStr.getBytes(StandardCharsets.UTF_8));

        // 3. 对 Base64 字符串进行 URL 编码（防止特殊字符截断）
        String encodedData = URLEncoder.encode(base64Data, "UTF-8");

        // 生成文件名（URL编码处理特殊字符）
        String fileName = URLEncoder.encode(
                detectReportDAO.getClientName() + "检测报告.xlsx",
                "UTF-8"
        );

        // 构建带数据的导出URL
        String exportUrl = String.format(
                "http://localhost:%s/ureport/excel?_u=file:检测报告.ureport.xml&_n=%s&data=%s",
                port,
                fileName,
                encodedData  // 使用detectData作为明确参数名
        );

        return ServerResponse.createBySuccess(exportUrl);
    }

    @PostMapping("/quotationExport")
    @ApiOperation(value = "报价单导出",response = ServerResponse.class,httpMethod = "POST")
    public ServerResponse quotationExport(@RequestBody QuotationDAO quotationDAO, HttpServletRequest request) throws JsonProcessingException, UnsupportedEncodingException {
        // 1. 将对象转为JSON
        String jsonStr = new ObjectMapper().writeValueAsString(quotationDAO);

        // 2. 使用 URL 安全的 Base64 编码（避免 + / = 问题）
        String base64Data = Base64.getUrlEncoder().encodeToString(jsonStr.getBytes(StandardCharsets.UTF_8));

        // 3. 对 Base64 字符串进行 URL 编码（防止特殊字符截断）
        String encodedData = URLEncoder.encode(base64Data, "UTF-8");

        // 生成直接携带数据的URL
        String fileName = URLEncoder.encode(quotationDAO.getProductName() + ".xlsx", "UTF-8");
        String exportUrl = "http://localhost:" + port + "/ureport/excel" +
                "?_u=file:报价单模板.ureport.xml" +
                "&_n=" + fileName +
                "&data=" + encodedData; // 关键：直接携带数据

        return ServerResponse.createBySuccess(exportUrl);
    }

    @GetMapping("/getCurrentColor")
    @ApiOperation(value = "获取当前颜色",response = ServerResponse.class,httpMethod = "GET")
    public ServerResponse getCurrentColor(){
        return ServerResponse.createBySuccess(deliveryColorService.getAllDeliveryColor());
    }

    @PostMapping("/updateColor")
    @ApiOperation(value = "修改颜色",response = ServerResponse.class,httpMethod = "POST")
    public ServerResponse updateColor(@RequestBody List<DeliveryColor> list){
        return ServerResponse.createBySuccess(deliveryColorService.updateColor(list));
    }

    @GetMapping("/getNumberRule")
    @ApiOperation(value = "获取送货单的编号规则",response = ServerResponse.class,httpMethod = "GET")
    public ServerResponse getNumberRule(){
        return ServerResponse.createBySuccess(numberRuleService.getNumberRule());
    }

    @PostMapping("/updateNumberRule")
    @ApiOperation(value = "修改送货单的编号规则",response = ServerResponse.class,httpMethod = "POST")
    public ServerResponse updateNumberRule(@RequestParam String numberRules){
        String numberRuleList = null;
        try {
            numberRuleList = numberRuleService.updateRule(numberRules);
        } catch (RException e) {
            log.error("修改送货单的编号规则时出错: {}", e.getMessage());
            return ServerResponse.createByError(e.getMessage());
        }
        return ServerResponse.createBySuccess(numberRuleList);
    }

    @GetMapping("/getTodayDeliveryList")
    @ApiOperation(value = "获取今天的送货单列表",response = ServerResponse.class,httpMethod = "GET")
    public ServerResponse getTodayDeliveryList(){
        List<Delivery> todayDeliveryList ;
        try {
            todayDeliveryList = deliveryService.getTodayDeliveryList();
        } catch (Exception e) {
            log.error("获取今天的送货单列表时出错: {}", e.getMessage());
            return ServerResponse.createByError(e.getMessage());
        }
        return ServerResponse.createBySuccess(todayDeliveryList);
    }

}
